
import java.io.*;
import java.util.Vector;

public class LaberintoA {

    int y, x, condicion = 0,x2,y2;
    Pila pilax, pilay, pilaxx, pilayy;
    int p[][] = new int[4][2];
    float s[] = new float[4];
    char m[][] = new char[2][2];
    char unica[][] = new char[2][2];
    Labe cm;
    char pos;
    outFiles oF; //pasar a clase externa!
    Vector lista=new Vector();

    LaberintoA() { //constructor de metodo laberintoA
        cm = new Labe();
        pilax = new Pila();
        pilay = new Pila();
        pilaxx = new Pila();
        pilayy = new Pila();
        a(); //obtenemos el valor de la matriz
        x = cm.y1; //guardamos coordenada de E
        y = cm.x1;//guardamos coordenada de E
        x2 = cm.y2; //guardamos coordenada de S
        y2 = cm.x2;//guardamos coordenada de S
        pilax.push(x);
        pilay.push(y);
        pilaxx.push(x);
        pilayy.push(y);
        guarda();
        
        System.out.println(""+x+""+y);
    }

    void a() { //inicializa los valores de la matriz
        try {
            m = cm.leeArch();
            unica = cm.leeArch();
        } catch (IOException e) {
            System.out.println("Error al intentar leer el archivo");
        }
    }

    void guarda() {
        String z="("+y+","+x+")";
        lista.addElement(z);
        pos = unica[y][x];        
//        gener(y,x);
        pilax.push(x);
        pilay.push(y);
        pilaxx.push(x);
        pilayy.push(y);
        modifica();
    }

    void movIzq() {
        x = x - 1;
        guarda();
    }

    void movDer() {
        x = x + 1;
        guarda();
    }

    void movArr() {
        y = y - 1;
        guarda();
    }

    void movAbajo() {
        y = y + 1;
        guarda();
    }

    void analiza() {//comienza la variacion genetica iterando en todas direccion
        
        int mov;
        
        
        if (pos == 'S') {
            System.out.println("Analizando Laberinto");
            return;

        }

        mov=buscarMov();
        if(mov==10000){
            condicion =0;
        }
        else
            condicion = 1;
        
        switch(mov){
            case 0:
                movArr();
                break;
            case 1:
                movAbajo();
                break;
            case 2:
                movDer();
                break;
            case 3:
                movIzq();
                break;
            default:
                System.out.println("Error");
                break;
        }
        
        if (condicion == 0) {
            if (regresa(1) == 1) {
                return;
            }
        }
        condicion = 0;

        analiza();
    }

    int buscarMov(){
        int result[] = new int[4];
        int temp, mov=0;
        
        result[0]=analizaArriba();
        result[1]=analizaAbajo();
        result[2]=analizaDerecha();
        result[3]=analizaIzquierda();
        
        temp=result[0];
        for(int i=0; i<3; i++){
            if(temp>result[i+1]){
                temp=result[i+1];
                mov=i+1;
            }
        }
        //System.out.println(""+result[0]+"    "+result[1]+"     "+result[2]+"    "+result[3]+"    "+mov);
        return mov;
    }
    
    int analizaAbajo(){
        int resX, resY, res;
        if(m[y + 1][x]!='N' && m[y + 1][x]!='*'){ 
           // System.out.println("Abajo "+x+""+(y+1)+""+m[y+1][x]);
            if(x<=x2){
                resX=x2-x;
            }
            else
                resX=x-x2;
            
            if((y+1)<=y2){
                resY=y2-(y+1);
            }
            else
                resY=(y+1)-y2;
            
            res=resX+resY;           
        }
        else
            res=10000;
        return res;
    }
    
    int analizaDerecha(){
        int resX, resY, res;
        if(m[y][x + 1]!='N' && m[y][x + 1]!='*'){
            
            if((x+1)<=x2){
                resX=x2-(x+1);
            }
            else
                resX=(x+1)-x2;
            
            if(y<=y2){
                resY=y2-y;
            }
            else
                resY=y-y2;
            
            res=resX+resY;           
        }
        else
            res=10000;
        return res;
    }
    
    int analizaIzquierda(){
        int resX, resY, res;
        if(m[y][x - 1]!='N' && m[y][x - 1]!='*'){    
            if((x-1)<=x2){
                resX=x2-(x-1);
            }
            else
                resX=(x-1)-x2;
            
            if(y<=y2){
                resY=y2-y;
            }
            else
                resY=y-y2;
            
            res=resX+resY;           
        }
        else
            res=10000;
        return res;
    }
    
    int analizaArriba(){
        int resX, resY, res;
        if(m[y - 1][x]!='N' && m[y - 1][x]!='*'){  
            //System.out.println(""+x+""+(y-1)+""+m[y-1][x]);
            if(x<=x2){
                resX=x2-x;
            }
            else
                resX=x-x2;
            
            if((y-1)<=y2){
                resY=y2-(y-1);
            }
            else
                resY=(y-1)-y2;
            
            res=resX+resY;           
        }
        else
            res=10000;
        return res;
    }
    
    int regresa() {
        if (pilax.tos != -1 && pilay.tos != -1) {
            x = pilax.pop();
            y = pilay.pop();
            pos = unica[y][x];
            return 0;
        } else {
            System.out.println("No hay salida");
            return 1;
        }
    }

    int regresa(int a) {
        if (pilaxx.tos != -1 && pilayy.tos != -1) {
            x = pilaxx.pop();
            y = pilayy.pop();
            pos = unica[y][x];
            return 0;
        } else {
            System.out.println("No hay salida");
            return 1;
        }
    }

    void modifica() {
        while (pilax.tos != -1 && pilay.tos != -1) {
            m[y][x] = '*';
            regresa();
        }
    }

    void start() {
        analiza();//empieza la generacion de individuos
        System.out.println("Laberinto");
        imp(unica);
        finalM(m);
        System.out.println("\n");
        System.out.println("\nSolucion Encontrada");
        modifica();
        imp(m);
        gener();
        //oF.finalM(m,cm.bb,cm.aa);
        
    }

    void imp(char d[][]) {
        for (int i = 0; i < cm.bb; i++) {
            System.out.print("\n");
            for (int j = 0; j < cm.aa; j++) {
                System.out.print(d[i][j]);
            }
        }
        System.out.print("\n\n");
    }
    
    void finalM(char m[][]) {
        try {
            FileWriter fw = new FileWriter("res.txt");

            for (int i = 0; i < cm.bb; i++) {
                fw.write("\n");
                for (int j = 0; j < cm.aa; j++) {
                    fw.write(m[i][j]);
                }
            }
            fw.write("\n");
            fw.close();
        } catch (Exception e) {
        }
    }
    
    void gener() {
        try {
            FileWriter fw = new FileWriter("generaciones.txt",true);
            
            for(int i=1;i<lista.size();i++)
            {
            
            String w= ""+lista.elementAt(i);              
            fw.write(w);          
            if (i%4==0)
            {
            fw.write("\n");
            }
            }
            fw.close();
        } catch (Exception e) {
        }
    }

    public static void main(String[] args) {

        LaberintoA z = new LaberintoA();
        z.start();
    }
}
